#pragma once

#include "gtest/gtest.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Common/Constant.h"
#include "../Gauss3DTetra4.h"

using SG::DataStructure::Common::Real;
using SG::DataStructure::Common::TOLERANCE;
using SG::FEMSolver::Element::Gauss3DTetra4;

class Gauss3DTetra4Test : public ::testing::Test
{
public:
    void SetUp () override
    {
        m_integForm = Gauss3DTetra4 ();
    }
protected:
    Gauss3DTetra4 m_integForm;
};

TEST_F (Gauss3DTetra4Test, GetPointSize)
{
    ASSERT_TRUE (4 == m_integForm.GetPointSize ());
}

TEST_F (Gauss3DTetra4Test, GetPoint)
{
    // Test data
    auto point = m_integForm.GetPoint (0);

    // Target data
    const Real a{0.13819660};
    const Real b{0.58541020};

    // Check Point 1
    ASSERT_NEAR (point.m_weight, 0.25, TOLERANCE);
    ASSERT_NEAR (point.m_x, a, TOLERANCE);
    ASSERT_NEAR (point.m_y, a, TOLERANCE);
    ASSERT_NEAR (point.m_z, a, TOLERANCE);

    // Check Point 2
    point = m_integForm.GetPoint (1);
    ASSERT_NEAR (point.m_weight, 0.25, TOLERANCE);
    ASSERT_NEAR (point.m_x, b, TOLERANCE);
    ASSERT_NEAR (point.m_y, a, TOLERANCE);
    ASSERT_NEAR (point.m_z, a, TOLERANCE);

    // Check Point 3
    point = m_integForm.GetPoint (2);
    ASSERT_NEAR (point.m_weight, 0.25, TOLERANCE);
    ASSERT_NEAR (point.m_x, a, TOLERANCE);
    ASSERT_NEAR (point.m_y, b, TOLERANCE);
    ASSERT_NEAR (point.m_z, a, TOLERANCE);

    // Check Point 4
    point = m_integForm.GetPoint (3);
    ASSERT_NEAR (point.m_weight, 0.25, TOLERANCE);
    ASSERT_NEAR (point.m_x, a, TOLERANCE);
    ASSERT_NEAR (point.m_y, a, TOLERANCE);
    ASSERT_NEAR (point.m_z, b, TOLERANCE);
}